import useMemberStore from '@/stores/member';
import { t } from '@/locale';
import { getToken, getAppChannel, getSiteId, redirect, currRoute, isUrl } from './common';
import { getPlatform } from './formatting';
import qs from 'qs';

interface RequestConfig {
	showErrorMessage?: boolean;
	showSuccessMessage?: boolean;
	isYuDao?: boolean;
}

interface RequestOptions extends UniNamespace.RequestOptions, RequestOptions { }

class Request {
	private baseUrl: string;
	private yudaoBaseUrl: string;

	private config: RequestOptions = {
		url: '',
		header: {}
	};

	constructor() {
		// #ifdef H5
		this.baseUrl = import.meta.env.VITE_APP_BASE_URL || `${location.origin}/api/`;
		this.yudaoBaseUrl = import.meta.env.VITE_YUDAO_APP_BASE_URL;

		// #endif
		// #ifndef H5
		this.baseUrl = import.meta.env.VITE_APP_BASE_URL;
		this.yudaoBaseUrl = import.meta.env.VITE_YUDAO_APP_BASE_URL;

		// #endif
		this.baseUrl.substr(-1) != '/' && (this.baseUrl += '/');
		this.config.header['platform'] = getPlatform().name
		try {
			if (process.env.NODE_ENV == 'development') {
				this.config.header[import.meta.env.VITE_REQUEST_HEADER_SITEID_KEY] = getSiteId(import.meta.env.VITE_SITE_ID || uni.getStorageSync('wap_site_id'));
			} else {
				this.config.header[import.meta.env.VITE_REQUEST_HEADER_SITEID_KEY] = getSiteId(import.meta.env.VITE_SITE_ID || uni.getStorageSync('wap_site_id'));
			}
			this.config.header[import.meta.env.VITE_REQUEST_HEADER_CHANNEL_KEY] = getAppChannel();
		} catch (e) { }
	}

	/**
	 * 请求拦截器
	 */
	private requestInterceptors() {
		// 携带token site-id
		try {
			getToken() && (this.config.header[import.meta.env.VITE_REQUEST_HEADER_TOKEN_KEY] = getToken());
			this.config.header[import.meta.env.VITE_REQUEST_HEADER_CHANNEL_KEY] = getAppChannel();
			if (process.env.NODE_ENV == 'development') {
				this.config.header[import.meta.env.VITE_REQUEST_HEADER_SITEID_KEY] = getSiteId(import.meta.env.VITE_SITE_ID || uni.getStorageSync('wap_site_id'));
			} else {
				this.config.header[import.meta.env.VITE_REQUEST_HEADER_SITEID_KEY] = getSiteId(import.meta.env.VITE_SITE_ID || uni.getStorageSync('wap_site_id'));
			}
		} catch (e) { }
	}

	public get(url: string, data: AnyObject = {}, config: RequestConfig = {}) {
		return this.request('GET', url, data, config);
	}

	public post(url: string, data: AnyObject = {}, config: RequestConfig = {}) {
		return this.request('POST', url, data, config);
	}

	public put(url: string, data: AnyObject = {}, config: RequestConfig = {}) {
		return this.request('PUT', url, data, config);
	}

	public delete(url: string, data: AnyObject = {}, config: RequestConfig = {}) {
		return this.request('DELETE', url, data, config);
	}
	/**
	 * 发送上传请求
	 */
	public upload(url: string, data: AnyObject = {}, config: RequestConfig = {}) {
		this.requestInterceptors();

		const params = Object.assign(uni.$u.deepClone(this.config), config, {
			url: this.baseUrl + url,
			...data
		});
		if (config.isYuDao) {
			params.url = this.yudaoBaseUrl + url;
			params.header['tenant-id'] = getSiteId(import.meta.env.VITE_SITE_ID || uni.getStorageSync('wap_site_id'))
		}
		return new Promise((resolve, reject) => {
			uni.uploadFile({
				...params,
				success: (res) => {

					const data = JSON.parse(res.data);
					if (config && config.isYuDao) {
						if (data.code == 0) {
							config.showSuccessMessage && uni.showToast({ title: data.msg, icon: 'none' });
							resolve(data);
						} else {
							if (data.code != 0) {
								if (config.showErrorMessage !== false) uni.showToast({ title: data.msg, icon: 'none' });
							} else {
								this.handleAuthError(data.code);
							}
							reject(data);
						}

					} else {
						if (data.code == 1) {
							config.showSuccessMessage && uni.showToast({ title: data.msg, icon: 'none' });
							resolve(data);
						} else {
							if (data.code == 400) {
								if (config.showErrorMessage !== false) uni.showToast({ title: data.msg, icon: 'none' });
							} else {
								this.handleAuthError(data.code);
							}
							reject(data);
						}

					}


				},
				fail: (res) => {
					reject(res);
				}
			});
		});
	}

	/**
	 * 发送请求
	 */
	private request(method: string, url: string, data?: AnyObject, config: RequestConfig = {}) {
		this.requestInterceptors();

		const params = Object.assign(uni.$u.deepClone(this.config), config, {
			url: this.baseUrl + url,
			method
		});

		if (config.isYuDao) {
			params.url = this.yudaoBaseUrl + url;
			params.header['tenant-id'] = getSiteId(import.meta.env.VITE_SITE_ID || uni.getStorageSync('wap_site_id'))
		}

		if (params.method.toUpperCase() == 'GET' && !uni.$u.test.empty(data)) {
			params.url += '?' + qs.stringify(data);
		} else {
			params.data = data;
		}

		return new Promise((resolve, reject) => {
			uni.request({
				...params,
				success: (res) => {
					const data = res.data;

					if (config && config.isYuDao) {
						// 如果是芋道的接口

						if (data.code == 0) {
							config.showSuccessMessage && uni.showToast({ title: data.msg, icon: 'none' });

							resolve(data);
						} else {

							if (data.code !== 0) {
								if (config.showErrorMessage !== false) uni.showToast({ title: data.msg, icon: 'none' });
							}
							if (data.code == 401) {
								useMemberStore().logout();

							} else {
								uni.showToast({ title: data.msg, icon: 'none' })
								this.handleAuthError(data.code);
							}
							reject(data);
						}

					} else {
						if (data.code == 1) {
							config.showSuccessMessage && uni.showToast({ title: data.msg, icon: 'none' });

							resolve(data);
						} else {
							if (data.code == 0 || data.code == 400) {
								if (config.showErrorMessage !== false) uni.showToast({ title: data.msg, icon: 'none' })
							} else {
								this.handleAuthError(data.code)
							}
							reject(data);
						}
					}


				},
				fail: (res) => {
					reject(res);
				},
				complete: (res) => {
					this.handleRequestFail(res);
				}
			});
		});
	}

	private handleAuthError(code: number) {
		switch (code) {
			case 401:
				useMemberStore().logout();
				break;
			case 402:
				if (currRoute().indexOf('app/pages/index/close') != -1) return;
				redirect({ url: '/app/pages/index/close', mode: 'reLaunch' });
				break;
			case 403:
				if (currRoute().indexOf('app/pages/index/nosite') != -1) return;
				redirect({ url: '/app/pages/index/nosite', mode: 'switchTab' });
				break;
		}
	}

	private handleRequestFail(res) {
		if (res.errMsg && res.errMsg == 'request:ok') {
			if (typeof res.data == 'string') {
				// #ifdef H5
				const err = (isUrl(this.baseUrl) ? this.baseUrl : location.origin + this.baseUrl) + t('baseUrlError');
				// #endif
				// #ifndef H5
				const err = this.baseUrl + t('baseUrlError');
				// #endif
				uni.showToast({ icon: 'none', title: err });
				return;
			}
		}
		if (res.errMsg == 'request:fail') {
			uni.showToast({ icon: 'none', title: this.baseUrl + t('requestFail') });
			return;
		}
		if (res.errMsg && res.errMsg == 'request:fail url not in domain list') {
			uni.showToast({ icon: 'none', title: this.baseUrl + t('notInDomainList') });
			return;
		}
	}
}

export default new Request();
